package com.ruoyi.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.base.BaseEntity;
import com.ruoyi.common.constant.ResultConstants;
import com.ruoyi.common.enums.AmountType;
import com.ruoyi.common.enums.TxnType;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.support.Convert;
import com.ruoyi.common.utils.BigDecimalUtil;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.system.domain.WdyTransfer;
import com.ruoyi.system.domain.WdyTxnHistory;
import com.ruoyi.system.domain.WdyUser;
import com.ruoyi.system.mapper.WdyTransferMapper;
import com.ruoyi.system.service.IWdyTransferService;
import com.ruoyi.system.service.IWdyTxnHistoryService;
import com.ruoyi.system.service.IWdyUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * 资金划转 服务层实现
 * 
 * @author ruoyi
 * @date 2020-01-13
 */
@Service
public class WdyTransferServiceImpl extends ServiceImpl<WdyTransferMapper, WdyTransfer> implements IWdyTransferService
{
	@Autowired
	private IWdyUserService wdyUserService;
	@Autowired
	private IWdyTxnHistoryService wdyTxnHistoryService;

	/**
     * 查询资金划转信息
     * 
     * @param id 资金划转ID
     * @return 资金划转信息
     */
    @Override
	public WdyTransfer selectWdyTransferById(Long id)
	{
	    return baseMapper.selectWdyTransferById(id);
	}
	
	/**
     * 查询资金划转列表
     * 
     * @param wdyTransfer 资金划转信息
     * @return 资金划转集合
     */
	@Override
	public List<WdyTransfer> selectWdyTransferList(WdyTransfer wdyTransfer)
	{
	    return baseMapper.selectWdyTransferList(wdyTransfer);
	}
	
    /**
     * 新增资金划转
     * 
     * @param wdyTransfer 资金划转信息
     * @return 结果
     */
	@Override
	public int insertWdyTransfer(WdyTransfer wdyTransfer)
	{
	    return baseMapper.insertWdyTransfer(wdyTransfer);
	}
	
	/**
     * 修改资金划转
     * 
     * @param wdyTransfer 资金划转信息
     * @return 结果
     */
	@Override
	public int updateWdyTransfer(WdyTransfer wdyTransfer)
	{
	    return baseMapper.updateWdyTransfer(wdyTransfer);
	}

	/**
     * 删除资金划转对象
     * 
     * @param ids 需要删除的数据ID
     * @return 结果
     */
	@Override
	public int deleteWdyTransferByIds(String ids)
	{
		return baseMapper.deleteWdyTransferByIds(Convert.toStrArray(ids));
	}


	@Transactional(rollbackFor = Exception.class)
	@Override
	public void transfer(WdyTransfer wdyTransfer) {

		BigDecimal transferAmount = wdyTransfer.getAmount();
		if(transferAmount == null) {
			throw new BusinessException(ResultConstants.FI1000, "amount" + MessageUtils.message("not.null"));
		}
		transferAmount = BigDecimalUtil.getP2BigDecimal(transferAmount);
		if(transferAmount.compareTo(BigDecimal.ZERO) <= 0) {
			throw new BusinessException(ResultConstants.FI1000, "amount" + MessageUtils.message("param.error"));
		}
		wdyTransfer.setAmount(transferAmount);

		if(wdyTransfer.getFromType() == null) {
			throw new BusinessException(ResultConstants.FI1000, "fromType" + MessageUtils.message("not.null"));
		}

		AmountType fromType = AmountType.getByCode(wdyTransfer.getFromType());
		if(fromType == null) {
			throw new BusinessException(ResultConstants.FI1000, "fromType" + MessageUtils.message("not.null"));
		}

		if(wdyTransfer.getToType() == null) {
			throw new BusinessException(ResultConstants.FI1000, "toType" + MessageUtils.message("not.null"));
		}

		AmountType toType = AmountType.getByCode(wdyTransfer.getToType());
		if(toType == null) {
			throw new BusinessException(ResultConstants.FI1000, "toType" + MessageUtils.message("not.null"));
		}

		QueryWrapper<WdyUser> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("user_id", wdyTransfer.getUserId());
		queryWrapper.eq("del_flag", BaseEntity.NOT_DELETED);
		WdyUser user = wdyUserService.getOne(queryWrapper);

		WdyUser updateUser = new WdyUser();
		BigDecimal accountAmount;
		if(fromType == AmountType.CNN_WITHDRAW) {
			toType = AmountType.CNN;
			accountAmount = user.getCnnWithdrawAmount();
			updateUser.setCnnAmount(user.getCnnAmount().add(transferAmount));
			updateUser.setCnnWithdrawAmount(user.getCnnWithdrawAmount().subtract(transferAmount));
		} else if(fromType == AmountType.VC_WITHDRAW) {
			if(transferAmount.compareTo(BigDecimal.valueOf(1000)) < 0) {
				throw new BusinessException(ResultConstants.FI1000, fromType.getName() + "最低划转金额为1000");
			}
			accountAmount = user.getVcWithdrawAmount();
			updateUser.setVcWithdrawAmount(user.getVcWithdrawAmount().subtract(transferAmount));
			if(toType == AmountType.VC) {
				updateUser.setVcAmount(user.getVcAmount().add(transferAmount));
			} else if(toType == AmountType.VC_FUND) {
				updateUser.setVcFundAsset(user.getVcFundAsset().add(transferAmount));
			} else {
				throw new BusinessException(ResultConstants.FI1000, "toType" + MessageUtils.message("param.error"));
			}
		} else if(fromType == AmountType.VC){
			toType = AmountType.VC_FUND;
			accountAmount = user.getVcAmount();
			updateUser.setVcAmount(user.getVcAmount().subtract(transferAmount));
			updateUser.setVcFundAsset(user.getVcFundAsset().add(transferAmount));
		} else if(fromType == AmountType.VC_FUND) {
			toType = AmountType.VC;
			accountAmount = user.getVcFundAsset();
			updateUser.setVcFundAsset(user.getVcFundAsset().subtract(transferAmount));
			updateUser.setVcAmount(user.getVcAmount().add(transferAmount));
		} else {
			throw new BusinessException(ResultConstants.FI1000, "fromType" + MessageUtils.message("param.error"));
		}

		if(accountAmount.compareTo(transferAmount) < 0) {
			throw new BusinessException(ResultConstants.FI1000, fromType.getName() + "不足");
		}

		updateUser.setVersion(user.getVersion());
		if (!wdyUserService.update(updateUser, queryWrapper)) {
			throw new BusinessException(ResultConstants.EX9110, "系统繁忙，请稍后重试");
		}

		wdyTransfer.setToType(toType.getCode());
		this.save(wdyTransfer);

		WdyTxnHistory txnHistory = new WdyTxnHistory();
		txnHistory.setUserId(wdyTransfer.getUserId());
		txnHistory.setTxnId(String.valueOf(wdyTransfer.getId()));
		txnHistory.setTxnAmount(transferAmount.negate());
		txnHistory.setTxnType(TxnType.TRANSFER.getCode());
		txnHistory.setAmountType(fromType.getCode());
		txnHistory.setTxnDesc(TxnType.TRANSFER.getName());
		wdyTxnHistoryService.save(txnHistory);

		txnHistory = new WdyTxnHistory();
		txnHistory.setUserId(wdyTransfer.getUserId());
		txnHistory.setTxnId(String.valueOf(wdyTransfer.getId()));
		txnHistory.setTxnAmount(transferAmount);
		txnHistory.setTxnType(TxnType.TRANSFER.getCode());
		txnHistory.setAmountType(toType.getCode());
		txnHistory.setTxnDesc(TxnType.TRANSFER.getName());
		wdyTxnHistoryService.save(txnHistory);
	}
}
